import datetime
from xml.etree.ElementTree import Element, SubElement, tostring
import xml.etree.ElementTree as ET
from xml.dom import minidom
import threading

import requests

from Aes import Aes

class DataService:
    _lock = threading.Lock()
    
    applykey_url = "http://kfpttest.supnumber.cn:9011/cap/dataservice/ApplyKey.proxy";
    opendata_url = "http://kfpttest.supnumber.cn:9011/cap/dataservice/appDataServiceAuthen.proxy";
    
    ap_id = "752243"
    app_id = "300012473857"
    app_key = "0F2FDA7BC10356E5E0633FAE990AE0B5"
    seq = 0
    key = ""
    
    client_code = "zaixin_sms"
    
    expiry_date = -1
    
    def __init__(self):
        self._data = None

    def get_apply_key(self):
        with DataService._lock:
            date_format = "%Y%m%d%H%M%S"
            now_time = datetime.datetime.now().strftime(date_format)
            print(now_time)

            if int(now_time) > self.expiry_date:
                url = self.applykey_url + "?clientCode=" + self.client_code
                apply_key_xml = self.do_get(url)

                try:
                    apply_key_map = self.parse_apply_key(apply_key_xml)
                    self.key = apply_key_map.get("key")
                    self.seq = int(apply_key_map.get("seq"))
                    
                    self.expiry_date = (datetime.datetime.strptime(now_time, date_format) + datetime.timedelta(days=1)).strftime(date_format)
                except Exception as e:
                    print(e)
    
    def parse_apply_key(self, xml):
        apply_key_map = {}
        
        try:
            root = ET.fromstring(xml)
            for child in root:
                apply_key_map[child.tag] = child.text
        except Exception as e:
            print(e)
            
        return apply_key_map
        
    def create_xml(self, phone, regTime, servCode):
        OpenDataRequest = Element('OpenDataRequest')
        RequestSEQ = SubElement(OpenDataRequest, 'RequestSEQ')
        RequestTime = SubElement(OpenDataRequest, 'RequestTime')
        APID = SubElement(OpenDataRequest, 'APID')
        APPID = SubElement(OpenDataRequest, 'APPID')
        ServCode = SubElement(OpenDataRequest, 'ServCode')
        ServArgs = SubElement(OpenDataRequest, 'ServArgs')
        Phone = SubElement(ServArgs, 'Phone')
        RegTime = SubElement(ServArgs, 'RegTime')
        AuthCode = SubElement(ServArgs, 'AuthCode')
        PhoneAuthCode = SubElement(ServArgs, 'PhoneAuthCode')

        # 时间格式为 yyyyMMddHHmmssSSS
        nowTime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        # RequestSEQ.text =  self.app_id + nowTime + DataService.getSeq()
        RequestSEQ.text =  self.app_id + nowTime
        RequestTime.text = nowTime
        APID.text = self.ap_id
        APPID.text = self.app_id
        ServCode.text = servCode
        Phone.text = phone
        RegTime.text = regTime
        AuthCode.text = "afdasfdsaffa"
        PhoneAuthCode.text = "afd"

        xml_str = minidom.parseString(tostring(OpenDataRequest)).toprettyxml(indent="   ")
        return xml_str
    
    def do_post(self, url, xml):
        try:
            headers = {
                "Content-Type": "application/xml;charset=utf-8",
                "Authorization": f'accessname="{self.ap_id}#{self.app_id}",clientCode="{self.client_code}",code="{Aes.encrypt(self.ap_id + "#" + self.app_id + "#" + self.app_key + "#" + self.getSeq(), self.key)}",account=""'
            }
            response = requests.post(url, data=xml, headers=headers, timeout=10)
            response.raise_for_status()  # Raise exception if status is not 200
            resp_text = response.text
            return resp_text
        except requests.exceptions.RequestException as e:
            print(e)
            return None
        
    def do_get(self, url):
        try:
            response = requests.get(url, timeout=10)
            response.raise_for_status()  # Raise exception if status is not 200
            resp_text = response.text
            return resp_text
        except requests.exceptions.RequestException as e:
            print(e)
            return None
        
    def getSeq(self):
        with DataService._lock:
            self.seq += 1
            return str(self.seq)
    
